using UnityEngine;
using System.Collections;

public class KeyboardInput : MonoBehaviour {
	
	
	private Transform draggedObject;
	private Transform levelTransform;
	private int currentId;
	private GPObject startDragObj;
	
	private float fixUpdate;	
	private bool leftControl = false;
	
	void Awake(){
		fixUpdate = Time.time;
		levelTransform = LevelHandler.Instance.transform;
		currentId = 1;
	}
	
	void Update(){
		if(draggedObject != null){
			//full rotation
			//draggedObject.RotateAround(Vector3.forward,Input.GetAxis("Mouse ScrollWheel")/2);
			if(Input.GetAxis("Mouse ScrollWheel")>0){
				draggedObject.Rotate(new Vector3(0,0,22.5f));
			}else if(Input.GetAxis("Mouse ScrollWheel")<0){
				draggedObject.Rotate(new Vector3(0,0,-22.5f));
			}
			
			
		}
		
		if(Input.GetKeyDown(KeyCode.LeftControl))
    		leftControl = true;
		if(Input.GetKeyUp(KeyCode.LeftControl))
    		leftControl = false;
 
		if (leftControl && Input.GetKeyUp(KeyCode.RightArrow))
		{
			StatsHandler.Instance.setTime();
			Camera.mainCamera.GetComponent<GameHandler>().loadNextLevel();
		}
		
		if (leftControl && Input.GetKeyUp(KeyCode.LeftArrow))
		{
			StatsHandler.Instance.setTime();
			Camera.mainCamera.GetComponent<GameHandler>().loadPreviousLevel();
		}
		
		if (Input.GetKeyUp(KeyCode.Space))
		{
			StatsHandler.Instance.addHint();
		}
		
		
	}
	
	void OnGUI() {
		
	    Event e = Event.current;
	    if (e.isKey) {
			if(Time.time - fixUpdate < 0.2)return;
			fixUpdate = Time.time;
			
			RaycastHit hit;
			Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
			if(Physics.Raycast(ray.origin,ray.direction,out hit,Mathf.Infinity)){
				GameObject hitted = hit.transform.gameObject;
				ObjectType type = ObjectType.Unknown;
				
				if(hitted.layer == LayerMask.NameToLayer("GamePlane")){
					switch(e.keyCode){
					case KeyCode.Alpha1:
						if(LevelConstants.editorMode)
							type = ObjectType.LaserGenerator;
						break;
					case KeyCode.Alpha2:
						if(LevelConstants.editorMode)
							type = ObjectType.LaserReceiver;
						break;
					case KeyCode.Alpha3:
						type = ObjectType.Mirror;
						break;
					case KeyCode.Alpha4:
						type = ObjectType.Filter;
						break;
					case KeyCode.Alpha5:
						type = ObjectType.Mixer;
						break;
					case KeyCode.Alpha6:
						type = ObjectType.Divider;
						break;
					default:
						break;
					}
					
					if(type != ObjectType.Unknown){
						while(LevelHandler.Instance.tangibles.ContainsKey(currentId)){
							currentId++;	
						}
						GameObject newObject = LevelHandler.Instance.createObject(new GPObject(currentId, type ,hit.point.x,hit.point.y,0,Color.white));
						
						if(newObject != null && type != ObjectType.Filter){
							
							currentId++;
						
							THistory.Instance.addAction(new TAddAction(new GPObject(newObject)));
						}
						
						
					}
				}
				
				
				if(hitted.layer == LayerMask.NameToLayer("GPObject")){
					Transform container = hitted.transform;
					
					while(container.parent != levelTransform){
						container = container.parent;
					}
					
					switch(e.keyCode){
					case KeyCode.S:
						if(!container.gameObject.GetComponent<LightRayHandler>().isFixed){
							LevelHandler.Instance.tangibles.Remove(container.gameObject.GetComponent<LightRayHandler>().Id);
							
							GPObject gpObj = new GPObject(container.gameObject);
							if(!(gpObj.Type == ObjectType.Filter && gpObj.ObjColor == Color.white)){
								THistory.Instance.addAction(new TRemoveAction(gpObj));
							}
							Destroy(container.gameObject);
						}
						break;
					case KeyCode.F:
						if(LevelConstants.editorMode){
							if(container.gameObject.GetComponent<LightRayHandler>().isFixed){
								container.gameObject.GetComponent<LightRayHandler>().isFixed = false;
								Debug.Log ("Unfixed");
							}else{
								container.gameObject.GetComponent<LightRayHandler>().isFixed = true;
								Debug.Log ("Fixed");
							}
						}
						break;
					default:
						break;
					}
				}
				
			}

			
	    }
		
		if(e.isMouse){
			
			if(e.type == EventType.mouseUp){
				if(draggedObject != null){
					GPObject gpObj = new GPObject(draggedObject.gameObject);
					if(!(gpObj.Type == ObjectType.Filter && gpObj.ObjColor == Color.white)){
						THistory.Instance.addAction(new TMoveAction(startDragObj,gpObj));
					}
				}
				draggedObject = null;
			}else if(e.type == EventType.mouseDrag){
				if(draggedObject != null){
					Vector3 newPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);	
					draggedObject.position = new Vector3(newPos.x,newPos.y,0);
				}
			}else{
				
				RaycastHit hit;
				Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
				if(Physics.Raycast(ray.origin,ray.direction,out hit,Mathf.Infinity)){
					GameObject hitted = hit.collider.transform.gameObject;
					
					if(hitted.GetComponent<LightRayHandler>() != null){
						if(hitted.GetComponent<LightRayHandler>().isFixed){
							return;
						}
					}
					
					
					
					if(hitted.layer == LayerMask.NameToLayer("Clickable")){
					
						hitted.GetComponent<Clickable>().onClick();
					}
					
					if(hitted.layer == LayerMask.NameToLayer("GPObject")){
						
						Transform container = hitted.transform;
						
						while(container.parent != levelTransform){
							container = container.parent;
						}
						
						draggedObject = container;
						
						startDragObj = new GPObject(container.gameObject);
						
					}
				}
			}
		}
		
	}
	
}
